/**
 * 绘制工具模块
 * @description 提供地图上的绘制功能，包括点、线、面、圆等几何图形的绘制
 */

import { ref, reactive } from 'vue';

/**
 * 绘制工具类
 * @class DrawingTools
 */
export class DrawingTools {
  constructor(mapEngine) {
    this.mapEngine = mapEngine;
    this.drawLayer = null;
    this.currentTool = null;
    this.isDrawing = false;
    this.drawConfig = reactive({
      style: {
        point: {
          color: '#ff0000',
          pixelSize: 8,
          outlineColor: '#ffffff',
          outlineWidth: 2
        },
        line: {
          color: '#ffff00',
          width: 3,
          clampToGround: true
        },
        polygon: {
          color: 'rgba(255,255,0,0.3)',
          outline: true,
          outlineColor: '#ffff00',
          outlineWidth: 2,
          clampToGround: true
        },
        circle: {
          color: 'rgba(0,255,0,0.3)',
          outline: true,
          outlineColor: '#00ff00',
          outlineWidth: 2
        },
        rectangle: {
          color: 'rgba(255,0,0,0.3)',
          outline: true,
          outlineColor: '#ff0000',
          outlineWidth: 2
        }
      },
      showMeasurement: true,
      autoComplete: true
    });

    // 事件回调
    this.callbacks = {
      onDrawStart: null,
      onDrawing: null,
      onDrawEnd: null,
      onDrawCancel: null
    };

    this.init();
  }

  /**
   * 初始化绘制工具
   * @private
   */
  init() {
    const map = this.mapEngine?.getInstance();
    if (!map) return;

    // 创建绘制图层
    this.drawLayer = new mars3d.layer.GraphicLayer({
      name: "绘制图层",
      id: "drawing_layer"
    });
    map.addLayer(this.drawLayer);

    // 设置编辑点样式
    mars3d.DrawUtil.setAllEditPointStyle({ 
      pixelSize: 12,
      color: '#ff0000',
      outlineColor: '#ffffff',
      outlineWidth: 2
    });
  }

  /**
   * 开始绘制点
   * @param {Object} options - 绘制选项
   * @param {Object} options.style - 点样式
   * @param {Function} options.callback - 完成回调
   * @returns {Promise} 绘制结果
   */
  async drawPoint(options = {}) {
    const { style = {}, callback } = options;
    const finalStyle = { ...this.drawConfig.style.point, ...style };

    return this._startDraw('point', {
      type: "point",
      style: {
        color: finalStyle.color,
        pixelSize: finalStyle.pixelSize,
        outlineColor: finalStyle.outlineColor,
        outlineWidth: finalStyle.outlineWidth,
        clampToGround: true
      }
    }, callback);
  }

  /**
   * 开始绘制线
   * @param {Object} options - 绘制选项
   * @param {Object} options.style - 线样式
   * @param {Function} options.callback - 完成回调
   * @returns {Promise} 绘制结果
   */
  async drawPolyline(options = {}) {
    const { style = {}, callback } = options;
    const finalStyle = { ...this.drawConfig.style.line, ...style };

    return this._startDraw('polyline', {
      type: "polyline",
      style: {
        color: finalStyle.color,
        width: finalStyle.width,
        clampToGround: finalStyle.clampToGround,
        // 添加测量标签
        label: this.drawConfig.showMeasurement ? {
          text: "{measure}",
          font_size: 14,
          color: "#ffffff",
          background: true,
          backgroundColor: "rgba(0,0,0,0.7)"
        } : undefined
      }
    }, callback);
  }

  /**
   * 开始绘制多边形
   * @param {Object} options - 绘制选项
   * @param {Object} options.style - 多边形样式
   * @param {Function} options.callback - 完成回调
   * @returns {Promise} 绘制结果
   */
  async drawPolygon(options = {}) {
    const { style = {}, callback } = options;
    const finalStyle = { ...this.drawConfig.style.polygon, ...style };

    return this._startDraw('polygon', {
      type: "polygon",
      style: {
        color: finalStyle.color,
        outline: finalStyle.outline,
        outlineColor: finalStyle.outlineColor,
        outlineWidth: finalStyle.outlineWidth,
        clampToGround: finalStyle.clampToGround,
        // 添加面积标签
        label: this.drawConfig.showMeasurement ? {
          text: "{area}",
          font_size: 14,
          color: "#ffffff",
          background: true,
          backgroundColor: "rgba(0,0,0,0.7)",
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM
        } : undefined
      }
    }, callback);
  }

  /**
   * 开始绘制圆形
   * @param {Object} options - 绘制选项
   * @param {Object} options.style - 圆形样式
   * @param {Function} options.callback - 完成回调
   * @returns {Promise} 绘制结果
   */
  async drawCircle(options = {}) {
    const { style = {}, callback } = options;
    const finalStyle = { ...this.drawConfig.style.circle, ...style };

    return this._startDraw('circle', {
      type: "circle",
      style: {
        color: finalStyle.color,
        outline: finalStyle.outline,
        outlineColor: finalStyle.outlineColor,
        outlineWidth: finalStyle.outlineWidth,
        // 显示半径
        label: this.drawConfig.showMeasurement ? {
          text: "半径: {radius}",
          font_size: 14,
          color: "#ffffff",
          background: true,
          backgroundColor: "rgba(0,0,0,0.7)"
        } : undefined
      },
      drawShowRadius: true
    }, callback);
  }

  /**
   * 开始绘制矩形
   * @param {Object} options - 绘制选项
   * @param {Object} options.style - 矩形样式
   * @param {Function} options.callback - 完成回调
   * @returns {Promise} 绘制结果
   */
  async drawRectangle(options = {}) {
    const { style = {}, callback } = options;
    const finalStyle = { ...this.drawConfig.style.rectangle, ...style };

    return this._startDraw('rectangle', {
      type: "rectangle",
      style: {
        color: finalStyle.color,
        outline: finalStyle.outline,
        outlineColor: finalStyle.outlineColor,
        outlineWidth: finalStyle.outlineWidth,
        // 显示面积
        label: this.drawConfig.showMeasurement ? {
          text: "面积: {area}",
          font_size: 14,
          color: "#ffffff",
          background: true,
          backgroundColor: "rgba(0,0,0,0.7)"
        } : undefined
      }
    }, callback);
  }

  /**
   * 开始绘制箭头
   * @param {Object} options - 绘制选项
   * @param {Object} options.style - 箭头样式
   * @param {Function} options.callback - 完成回调
   * @returns {Promise} 绘制结果
   */
  async drawArrow(options = {}) {
    const { style = {}, callback } = options;

    return this._startDraw('straightArrow', {
      type: "straightArrow",
      style: {
        color: style.color || '#ff0000',
        outline: true,
        outlineColor: style.outlineColor || '#ffffff',
        outlineWidth: style.outlineWidth || 2,
        clampToGround: true
      }
    }, callback);
  }

  /**
   * 开始绘制文字标注
   * @param {Object} options - 绘制选项
   * @param {string} options.text - 文字内容
   * @param {Object} options.style - 文字样式
   * @param {Function} options.callback - 完成回调
   * @returns {Promise} 绘制结果
   */
  async drawText(options = {}) {
    const { text = '文字标注', style = {}, callback } = options;

    return this._startDraw('label', {
      type: "label",
      style: {
        text,
        font_size: style.fontSize || 16,
        color: style.color || '#ffffff',
        background: style.background !== false,
        backgroundColor: style.backgroundColor || 'rgba(0,0,0,0.7)',
        padding: style.padding || [5, 10],
        borderRadius: style.borderRadius || 3,
        clampToGround: true
      }
    }, callback);
  }

  /**
   * 通用绘制方法
   * @private
   * @param {string} type - 绘制类型
   * @param {Object} config - 绘制配置
   * @param {Function} callback - 完成回调
   * @returns {Promise} 绘制结果
   */
  async _startDraw(type, config, callback) {
    if (this.isDrawing) {
      this.stopDraw();
    }

    this.currentTool = type;
    this.isDrawing = true;

    try {
      // 触发开始绘制事件
      this._triggerCallback('onDrawStart', { type, config });

      // 开始绘制
      const graphic = await this.drawLayer.startDraw(config);

      // 绑定事件
      this._bindGraphicEvents(graphic, type);

      // 触发完成事件
      const result = {
        type,
        graphic,
        geometry: graphic.geometry,
        coordinates: this._extractCoordinates(graphic),
        properties: graphic.attr || {}
      };

      this._triggerCallback('onDrawEnd', result);
      
      if (callback) {
        callback(result);
      }

      return result;

    } catch (error) {
      console.error('Draw error:', error);
      this._triggerCallback('onDrawCancel', { type, error });
      throw error;
    } finally {
      this.isDrawing = false;
      this.currentTool = null;
    }
  }

  /**
   * 绑定图形事件
   * @private
   * @param {Object} graphic - 图形对象
   * @param {string} type - 图形类型
   */
  _bindGraphicEvents(graphic, type) {
    // 点击事件
    graphic.on(mars3d.EventType.click, (event) => {
      console.log(`${type} clicked:`, event);
    });

    // 编辑事件
    graphic.on(mars3d.EventType.editStart, (event) => {
      console.log(`${type} edit start:`, event);
    });

    graphic.on(mars3d.EventType.editStop, (event) => {
      console.log(`${type} edit stop:`, event);
      // 更新测量信息
      this._updateMeasurement(graphic, type);
    });
  }

  /**
   * 更新测量信息
   * @private
   * @param {Object} graphic - 图形对象
   * @param {string} type - 图形类型
   */
  _updateMeasurement(graphic, type) {
    if (!this.drawConfig.showMeasurement) return;

    try {
      let measurement = '';
      
      switch (type) {
        case 'polyline':
          measurement = mars3d.MeasureUtil.formatDistance(graphic.distance);
          break;
        case 'polygon':
        case 'rectangle':
          measurement = mars3d.MeasureUtil.formatArea(graphic.area);
          break;
        case 'circle':
          measurement = mars3d.MeasureUtil.formatDistance(graphic.radius);
          break;
      }

      if (measurement && graphic.label) {
        graphic.label.text = measurement;
      }
    } catch (error) {
      console.warn('Failed to update measurement:', error);
    }
  }

  /**
   * 提取坐标信息
   * @private
   * @param {Object} graphic - 图形对象
   * @returns {Array|Object} 坐标数据
   */
  _extractCoordinates(graphic) {
    try {
      const positions = graphic.positions || graphic.position;
      if (!positions) return null;

      if (Array.isArray(positions)) {
        return positions.map(pos => {
          const cartographic = mars3d.Cartographic.fromCartesian(pos);
          return {
            lng: mars3d.Math.toDegrees(cartographic.longitude),
            lat: mars3d.Math.toDegrees(cartographic.latitude),
            alt: cartographic.height
          };
        });
      } else {
        const cartographic = mars3d.Cartographic.fromCartesian(positions);
        return {
          lng: mars3d.Math.toDegrees(cartographic.longitude),
          lat: mars3d.Math.toDegrees(cartographic.latitude),
          alt: cartographic.height
        };
      }
    } catch (error) {
      console.warn('Failed to extract coordinates:', error);
      return null;
    }
  }

  /**
   * 停止当前绘制
   */
  stopDraw() {
    if (!this.isDrawing) return;

    try {
      this.drawLayer?.stopDraw();
      this.isDrawing = false;
      this.currentTool = null;
      this._triggerCallback('onDrawCancel', { reason: 'manual_stop' });
    } catch (error) {
      console.warn('Failed to stop drawing:', error);
    }
  }

  /**
   * 清除所有绘制内容
   */
  clear() {
    if (this.drawLayer) {
      this.drawLayer.clear();
    }
  }

  /**
   * 删除指定图形
   * @param {Object} graphic - 要删除的图形
   */
  removeGraphic(graphic) {
    if (this.drawLayer && graphic) {
      this.drawLayer.removeGraphic(graphic);
    }
  }

  /**
   * 获取所有绘制的图形
   * @returns {Array} 图形数组
   */
  getAllGraphics() {
    return this.drawLayer ? this.drawLayer.graphics : [];
  }

  /**
   * 导出绘制结果为GeoJSON
   * @returns {Object} GeoJSON对象
   */
  exportToGeoJSON() {
    const graphics = this.getAllGraphics();
    const features = graphics.map(graphic => {
      return {
        type: "Feature",
        geometry: this._graphicToGeometry(graphic),
        properties: graphic.attr || {}
      };
    });

    return {
      type: "FeatureCollection",
      features
    };
  }

  /**
   * 将图形转换为GeoJSON几何
   * @private
   * @param {Object} graphic - 图形对象
   * @returns {Object} GeoJSON几何对象
   */
  _graphicToGeometry(graphic) {
    // 这里需要根据不同的图形类型转换为相应的GeoJSON几何
    // 简化实现，实际需要更完善的转换逻辑
    const coordinates = this._extractCoordinates(graphic);
    
    if (!coordinates) return null;

    if (graphic.type === 'point') {
      return {
        type: "Point",
        coordinates: [coordinates.lng, coordinates.lat]
      };
    } else if (graphic.type === 'polyline') {
      return {
        type: "LineString",
        coordinates: coordinates.map(coord => [coord.lng, coord.lat])
      };
    } else if (graphic.type === 'polygon') {
      return {
        type: "Polygon",
        coordinates: [coordinates.map(coord => [coord.lng, coord.lat])]
      };
    }

    return null;
  }

  /**
   * 设置绘制样式
   * @param {string} type - 图形类型
   * @param {Object} style - 样式配置
   */
  setStyle(type, style) {
    if (this.drawConfig.style[type]) {
      Object.assign(this.drawConfig.style[type], style);
    }
  }

  /**
   * 设置事件回调
   * @param {string} event - 事件名称
   * @param {Function} callback - 回调函数
   */
  on(event, callback) {
    if (this.callbacks.hasOwnProperty(`on${event.charAt(0).toUpperCase()}${event.slice(1)}`)) {
      this.callbacks[`on${event.charAt(0).toUpperCase()}${event.slice(1)}`] = callback;
    }
  }

  /**
   * 触发回调
   * @private
   * @param {string} callbackName - 回调名称
   * @param {any} data - 回调数据
   */
  _triggerCallback(callbackName, data) {
    const callback = this.callbacks[callbackName];
    if (typeof callback === 'function') {
      try {
        callback(data);
      } catch (error) {
        console.error(`Error in ${callbackName} callback:`, error);
      }
    }
  }

  /**
   * 获取当前绘制状态
   * @returns {Object} 绘制状态
   */
  getDrawingStatus() {
    return {
      isDrawing: this.isDrawing,
      currentTool: this.currentTool,
      graphicsCount: this.getAllGraphics().length,
      config: { ...this.drawConfig }
    };
  }

  /**
   * 销毁绘制工具
   */
  destroy() {
    this.stopDraw();
    this.clear();
    
    const map = this.mapEngine?.getInstance();
    if (map && this.drawLayer) {
      map.removeLayer(this.drawLayer, true);
    }

    this.drawLayer = null;
    this.mapEngine = null;
    this.callbacks = {};
  }
}

/**
 * 绘制工具组合函数
 * @param {Object} mapEngine - 地图引擎实例
 * @returns {Object} 绘制工具API
 */
export function useDrawingTools(mapEngine) {
  const drawingTools = ref(null);

  /**
   * 初始化绘制工具
   */
  const initDrawingTools = () => {
    drawingTools.value = new DrawingTools(mapEngine);
    return drawingTools.value;
  };

  /**
   * 获取绘制工具实例
   */
  const getDrawingTools = () => drawingTools.value;

  /**
   * 销毁绘制工具
   */
  const destroy = () => {
    if (drawingTools.value) {
      drawingTools.value.destroy();
      drawingTools.value = null;
    }
  };

  return {
    drawingTools,
    initDrawingTools,
    getDrawingTools,
    destroy
  };
}
